package com.onec.service.channel.service.channel.jft;

import com.alibaba.fastjson.JSONObject;
import com.onec.service.api.dto.request.channel.ChannelMerchantReq;
import com.onec.service.api.dto.response.channel.ChannelMerchantResp;
import com.onec.service.api.enums.ProductEnum;
import com.onec.service.api.enums.StatusEnum;
import com.onec.service.api.enums.error.ChannelErrorEnum;
import com.onec.service.channel.entity.ChannelInfo;
import com.onec.service.channel.entity.ChannelKey;
import com.onec.service.channel.entity.ChannelMerchant;
import com.onec.service.channel.entity.ChannelMerchantBusiness;
import com.onec.service.channel.service.channel.base.BaseChannelMerchantDefaultService;
import com.onec.service.channel.service.channel.jft.util.JftProperties;
import com.onec.service.channel.service.channel.jft.util.JftRequestUtils;
import com.onec.service.channel.service.channel.jft.util.JftReturnModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.math.RoundingMode;
import java.util.Map;
import java.util.Optional;
import java.util.TreeMap;


/**
 * 佳付通通道对接
 *
 * @author ONEC
 */
@Service("merchant_jft")
public class ChannelMerchantJftServiceImpl extends BaseChannelMerchantDefaultService {

    private static final Logger logger = LoggerFactory.getLogger(ChannelMerchantJftServiceImpl.class);

    @Autowired
    JftProperties jftProperties;

    @Override
    public RoundingMode getRoundingMode() {
        return RoundingMode.HALF_UP;
    }

    @Override
    public boolean needRegister() {
        return true;
    }

    @Override
    public ChannelMerchantResp register(ChannelMerchantReq channelMerchantReq, ChannelInfo channelInfo) {
        // 处理佳付通2001 业务：
        Map<String, Object> requestParam = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
        requestParam.put("verCode", "1001");
        requestParam.put("chMerCode", channelMerchantReq.getOutCode());

        requestParam.put("merName", channelMerchantReq.getName());
        requestParam.put("realName", channelMerchantReq.getName());
        requestParam.put("merAddress", channelMerchantReq.getAddress());
        requestParam.put("idCard", channelMerchantReq.getIdCard());
        requestParam.put("mobile", channelMerchantReq.getPhone());

        requestParam.put("accountName", channelMerchantReq.getName());
        requestParam.put("accountNo", channelMerchantReq.getCardNo());
        requestParam.put("reservedMobile", channelMerchantReq.getPhone());

        requestParam.put("subBankCode", "105221020028");
        requestParam.put("subBankName", "中国工商银行");
        requestParam.put("settleAccType", "1");
        requestParam.put("serviceTel", channelMerchantReq.getPhone());
        requestParam.put("email", "111@2222");
        JftReturnModel jftReturnModel = resp(channelInfo, requestParam,
                jftProperties.getUrl() + jftProperties.getReg());
        return respRegisterStatus(jftReturnModel, channelMerchantReq, channelInfo);
    }

    /**
     * 开通产品
     *
     * @param
     * @return
     */
    @Override
    public ChannelMerchantResp productOpen(ChannelMerchantReq channelMerchantReq, ChannelInfo channelInfo) {

        ChannelMerchant channelMerchant = channelMerchantService
                .getAvailableChannelIdProductMerchantNo(channelInfo.getId(), channelMerchantReq.getMerchantNo(),
                        ProductEnum.DEFAULT);
        Map<String, Object> requestParam = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
        requestParam.put("verCode", "1001");
        requestParam.put("chMerCode", channelMerchant.getChannelMerchantNo());
        requestParam.put("tradeRate", channelMerchantReq.getRate());

        requestParam.put("busCode", channelMerchantReq.getChannelBusinessNo());
        requestParam.put("drawFee", channelMerchantReq.getFee());
        JftReturnModel jftReturnModel =
                resp(channelInfo, requestParam, jftProperties.getUrl() + jftProperties.getOpen());
        return respOpenStatus(jftReturnModel, channelMerchantReq, channelInfo);
    }

    /**
     * 处理入网
     *
     * @param jftReturnModel
     * @param
     * @param channelInfo
     * @return
     */
    private ChannelMerchantResp respRegisterStatus(JftReturnModel jftReturnModel, ChannelMerchantReq channelMerchantReq,
                                                   ChannelInfo channelInfo) {
        ChannelMerchantResp channelMerchantResp = ChannelMerchantResp.respMerchantStatus(ChannelErrorEnum.SUCCESS);
        StatusEnum statusEnum = StatusEnum.SUCCESS;
        if (jftReturnModel.isFailed()) {
            statusEnum = StatusEnum.FAILED;
            channelMerchantResp = ChannelMerchantResp.respMerchantStatus(ChannelErrorEnum.FAILED);
            channelMerchantResp.setMessage(jftReturnModel.getResMsg());
        }
        ChannelMerchant channelMerchant =
                updateMerchantChannel(channelInfo.getId(), ProductEnum.valueOf(channelMerchantReq.getProduct()), statusEnum,
                        channelMerchantReq.getMerchantNo(), jftReturnModel.getChMerCode(), jftReturnModel.getResMsg());
        channelMerchantResp.setChannelMerchantNo(channelMerchant.getChannelMerchantNo());
        channelMerchantResp.setBusinessNo(channelMerchantReq.getBusinessNo());
        return channelMerchantResp;
    }

    /**
     * 处理产品开通服务
     *
     * @param jftReturnModel
     * @param
     * @param channelInfo
     * @return
     */
    private ChannelMerchantResp respOpenStatus(JftReturnModel jftReturnModel, ChannelMerchantReq channelMerchantReq,
                                               ChannelInfo channelInfo) {
        ChannelMerchantResp channelMerchantResp = ChannelMerchantResp.respMerchantStatus(ChannelErrorEnum.SUCCESS);
        StatusEnum statusEnum = StatusEnum.SUCCESS;
        if (jftReturnModel.isFailed()) {
            statusEnum = StatusEnum.FAILED;
            channelMerchantResp = ChannelMerchantResp.respMerchantStatus(ChannelErrorEnum.FAILED);
            channelMerchantResp.setMessage(jftReturnModel.getResMsg());
        }
        ChannelMerchantBusiness channelMerchantBusiness = channelMerchantBusinessService
                .updateByMerchantNoBusinessNo(channelInfo.getId(), channelMerchantReq.getBusinessNo(), statusEnum,
                        channelMerchantReq.getMerchantNo(), jftReturnModel.getChMerCode(), jftReturnModel.getResMsg());
        channelMerchantResp.setChannelMerchantNo(channelMerchantBusiness.getChannelMerchantNo());
        channelMerchantResp.setBusinessNo(channelMerchantReq.getBusinessNo());
        return channelMerchantResp;
    }

//    /**
//     * 通道返回成功，处理成功订单.
//     * 商户注册等：
//     *
//     * @param
//     * @return
//     */
//    protected void respMerchantSettle(String merchantNo, String channelMerchantNo, long channelId, ProductEnum productEnum,
//                                      StatusEnum statusEnum, String message) {
//        ChannelMerchant channelMerchant =
//                updateMerchantChannel(channelId, productEnum, statusEnum, merchantNo, channelMerchantNo, message);
//
//        if (StatusEnum.isSuccess(statusEnum)) {
//
//        }
//
//    }

//    /**
//     * 处理变更费率
//     *
//     * @param jftReturnModel
//     * @param merchantInfo
//     * @param channelInfo
//     * @return
//     */
//    private ChannelMerchantResp respModifyCardRate(JftReturnModel jftReturnModel, MerchantInfo merchantInfo, ChannelInfo channelInfo, ChangeStatusEnum changeStatusEnum) {
//        ChangeStatusEnum statusEnum = ChangeStatusEnum.SUCCESS;
//        if (jftReturnModel.isSuccess()) {
//            statusEnum = ChangeStatusEnum.SUCCESS;
//        } else if (jftReturnModel.isFailed()) {
//            statusEnum = changeStatusEnum;
//        }
//        return this.respMerchantSettle(merchantInfo.getId(), channelInfo.getId(), merchantInfo.getProduct(), statusEnum, jftReturnModel.getResMsg());
//    }

    @Override
    public ChannelMerchantResp updateMerchantFee(ChannelMerchantReq channelMerchantReq, ChannelInfo channelInfo) {

        ChannelMerchant channelMerchant = channelMerchantService
                .getAvailableChannelIdProductMerchantNo(channelInfo.getId(), channelMerchantReq.getMerchantNo(),
                        ProductEnum.DEFAULT);

        Map<String, Object> requestParam = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
        requestParam.put("verCode", "1001");
        requestParam.put("chMerCode", channelMerchant.getChannelMerchantNo());

        requestParam.put("drawFee", channelMerchantReq.getFee());
        requestParam.put("tradeRate", channelMerchantReq.getRate());
        requestParam.put("T1FeeRate", channelMerchantReq.getAddress());
        requestParam.put("busCode", channelMerchantReq.getChannelBusinessNo());
        JftReturnModel jftReturnModel = resp(channelInfo, requestParam, jftProperties.getUrl()
                + jftProperties.getRate_modify());
        return respOpenStatus(jftReturnModel, channelMerchantReq, channelInfo);
    }

    @Override
    public ChannelMerchantResp queryMerchantApi(ChannelMerchantReq channelMerchantReq, ChannelInfo channelInfo) {
        return null;
    }

    @Override
    public ChannelMerchantResp queryMerchantAmountApi(ChannelMerchantReq channelMerchantReq, ChannelInfo channelInfo) {
        return null;
    }

    @Override
    public ChannelMerchantResp querySettleApi(ChannelMerchantReq channelMerchantReq, ChannelInfo channelInfo) {
        return null;
    }

    /**
     * 通道变更结算卡：
     *
     * @param
     * @return
     */
    @Override
    public ChannelMerchantResp updateMerchantSettle(ChannelMerchantReq channelMerchantReq, ChannelInfo channelInfo) {

        Map<String, Object> requestParam = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
        requestParam.put("verCode", "1001");

        ChannelMerchant channelMerchant = channelMerchantService.getAvailableChannelIdProductMerchantNo(
                channelInfo.getId(), channelMerchantReq.getMerchantNo(), ProductEnum.DEFAULT);
        requestParam.put("chMerCode", channelMerchant.getChannelMerchantNo());

        requestParam.put("accountName", channelMerchantReq.getName());
        requestParam.put("accountNo", channelMerchantReq.getName());
        requestParam.put("reservedMobile", channelMerchantReq.getAddress());
        requestParam.put("subBankCode", channelMerchantReq.getIdCard());
        requestParam.put("settleAccType", channelMerchantReq.getPhone());
        JftReturnModel jftReturnModel = resp(channelInfo, requestParam, jftProperties.getUrl()
                + jftProperties.getBankModify());

        return respRegisterStatus(jftReturnModel, channelMerchantReq, channelInfo);
    }


    @Override
    public ChannelMerchantResp notifyMerchantApi(HttpServletRequest request) {
        return null;
    }

    @Override
    public ChannelMerchantResp notifySettleApi(HttpServletRequest request) {
        return null;
    }

    /**
     * 验证渠道是否可以走该产品的交易：
     *
     * @param
     * @return
     */
    @Override
    public boolean checkMerchantTradeValue(ChannelMerchantReq channelMerchantReq, ChannelInfo channelInfo) {
        // 是否需要签约
        logger.info("当前通道编号：{}，是否需要注册：{}", channelInfo.getNo(), this.needRegister());
        ProductEnum productEnum = ProductEnum.valueOf(channelMerchantReq.getProduct());
        ChannelMerchant channelMerchant = channelMerchantService.findByChannelIdProductMerchantNo(channelInfo.getId(),
                channelMerchantReq.getMerchantNo(), productEnum);
        channelMerchant = Optional.ofNullable(channelMerchant).orElseGet(() ->
                channelMerchantService.createChannelMerchant(channelInfo, channelMerchantReq.getMerchantNo(), productEnum));

        logger.info("当前通道编号：{}，商户当前状态：{}", channelInfo.getCode(), channelMerchant.getStatus());
        if (StatusEnum.isSuccess(channelMerchant.getStatus())) {
            return true;
        }
        ChannelMerchantResp responseMerchant;
        if (StatusEnum.isInit(channelMerchant.getStatus())) {

            responseMerchant = this.register(channelMerchantReq, channelInfo);

            logger.info("当前通道编号：{}，商户注册结果：{}", channelInfo.getNo(), channelMerchant.getStatus());
            if (responseMerchant.isSuccess()) {
                return false;
            }
            responseMerchant = this.productOpen(channelMerchantReq, channelInfo);

        }
        if (StatusEnum.isFailed(channelMerchant.getStatus())) {
            // 查询上游注册情况：
        }
        if (StatusEnum.isDoing(channelMerchant.getStatus())) {
            responseMerchant = this.productOpen(channelMerchantReq, channelInfo);

        }
        return false;
    }


    /**
     * 佳付通公共请求返回方法
     *
     * @param channelInfo
     * @param requestParam
     * @return
     */
    private JftReturnModel resp(ChannelInfo channelInfo, Map<String, Object> requestParam, String serviceUrl) {
        ChannelKey channelKey = channelKeyService.findByChannelId(channelInfo.getId());
        logger.info("佳付通请求明文：{}", JSONObject.toJSONString(requestParam));
        return JftRequestUtils.requestMap(channelKey, requestParam, channelInfo.getNo(), serviceUrl);

    }
}
